extern crate proc_macro;

use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput};

#[proc_macro_derive(HelloMacro)]
/// 定义宏 HelloMacro 的派生实现函数
///
/// 此函数用于为使用 `#[derive(HelloMacro)]` 属性的类型自动生成 `HelloMacro` 特性实现。
/// 它解析输入的 Rust 代码结构，并调用 `impl_hello_macro` 函数生成具体的 trait 实现代码。
///
/// 参数:
/// - input: TokenStream，表示宏输入的 Token 流，通常是一个结构体或枚举的定义
///
/// 返回值:
/// 返回一个 TokenStream，包含生成的 trait 实现代码
pub fn hello_macro_derive(input: TokenStream) -> TokenStream {
    // 将输入的 TokenStream 解析为语法树结构 (AST)
    let ast = parse_macro_input!(input as DeriveInput);

    // 调用 impl_hello_macro 函数生成 trait 实现代码并返回
    impl_hello_macro(&ast)
}

/**
 * 实现HelloMacro特性
 * 
 * 此函数通过接收一个syn::DeriveInput类型的参数，来生成实现HelloMacro特性的代码
 * 它主要用于通过宏来自动实现HelloMacro特性，该特性包含一个hello_marco方法
 * 该方法打印出一个介绍性的信息，包括特性的名称
 * 
 * 参数:
 * - ast: 一个引用，指向derive宏应用的类型的信息，包括类型的名称等
 * 
 * 返回值:
 * 返回一个TokenStream，即生成的实现HelloMacro特性的代码流
 */
fn impl_hello_macro(ast: &syn::DeriveInput) -> TokenStream {
    // println!("{:#?}", ast); // 格式化打印 DeriveInput 内容
    // 获取类型的名字
    let name = &ast.ident;
    
   
    // 使用quote宏生成实现HelloMacro特性的代码
    let gen = quote! {
        // 为类型实现HelloMacro特性
        impl HelloMacro for #name {
            // 实现hello_marco方法
            fn hello_marco() {
                // 打印介绍性的信息，包括特性的名称
                println!("Hello,Marco! My name is {}!",stringify!(#name));
            }
        }
    };
    // 将生成的代码转换为TokenStream并返回
    gen.into()
}